//
//  String+Extension.swift
//  Feicui
//
//  Created by people on 2018/3/27.
//  Copyright © 2018年 zhan. All rights reserved.
//

import Foundation
import UIKit
import CommonCrypto
extension String {
    ///-------------------字符宽高--------------------
    ///获取宽度
    public func ga_widthForComment(fontSize: CGFloat, height: CGFloat = 15) -> CGFloat {
        let font = UIFont.systemFont(ofSize: fontSize)
        let rect = NSString(string: self).boundingRect(with: CGSize(width: CGFloat(MAXFLOAT), height: height), options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font: font], context: nil)
        return ceil(rect.width)
    }
    
    ///获取高度
    public func ga_heightForComment(fontSize: CGFloat, width: CGFloat) -> CGFloat {
        let font = UIFont.systemFont(ofSize: fontSize)
        let rect = NSString(string: self).boundingRect(with: CGSize(width: width, height: CGFloat(MAXFLOAT)), options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font: font], context: nil)
        return ceil(rect.height)
    }
    ///获取高度
    public func ga_heightForComment(fontSize: CGFloat, width: CGFloat, maxHeight: CGFloat) -> CGFloat {
        let font = UIFont.systemFont(ofSize: fontSize)
        let rect = NSString(string: self).boundingRect(with: CGSize(width: width, height: CGFloat(MAXFLOAT)), options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font: font], context: nil)
        return ceil(rect.height)>maxHeight ? maxHeight : ceil(rect.height)
    }

    ///获取文字的行数
    public func ga_TextLines(width:CGFloat,fontSize:CGFloat) ->Int {
        let size  = self.size(withAttributes: [NSAttributedString.Key.font : UIFont.systemFont(ofSize: fontSize)])
        return Int(ceil((size.width)/width))
    }
    
    ///获取文字的行数 size
   public func ga_TextSize(width:CGFloat,fontSize:CGFloat) -> CGSize {
        let font:UIFont! = UIFont.systemFont(ofSize: fontSize)
    let attributes : [NSAttributedString.Key : Any] = [NSAttributedString.Key.font:font as Any]
        let option = NSStringDrawingOptions.usesLineFragmentOrigin
        let rect:CGRect = self.boundingRect(with: CGSize(width: width, height: CGFloat(MAXFLOAT)), options: option, attributes: attributes , context: nil)
        return rect.size
    }

    
    
    ///-------------------富文本处理--------------------
    ///html字符串转 NSMutableAttributedString
    public func htmlToAttribute() -> NSMutableAttributedString {
        let attributeString = try! NSMutableAttributedString(data: self.data(using: .unicode, allowLossyConversion: true)!, options: [.documentType:NSAttributedString.DocumentType.html,.characterEncoding:String.Encoding.utf8.rawValue], documentAttributes: nil)
        return attributeString
    }
    

    
    
    ///-------------------时间处理-----------------------
    ///时间戳String->String(Date)
    public func timeStamp(withFormate formate:String="yyyy-MM-dd HH:mm:ss") -> String {
        let timeInt = Int(self)
        let timeInterval:TimeInterval = TimeInterval(timeInt!)
        let date = NSDate(timeIntervalSince1970: timeInterval)
        let dateformatter = DateFormatter()
        dateformatter.dateFormat = formate //自定义日期格式
        let time = dateformatter.string(from: date as Date)
        return time
    }
    
    ///时间字符串->时间字符串
    public func stringDataToStringData(withFormate formate:String="yyyy-MM-dd HH:mm:ss") -> String{
        let date = self.toToDay()
        let dateformatter = DateFormatter()
        dateformatter.dateFormat = formate //自定义日期格式
        let time = dateformatter.string(from: date as Date)
        return time
    }
    ///日期转换 String->Int 时间戳
    public func toDateInterval() -> Int {
        let dfmatter = DateFormatter()
        dfmatter.dateFormat="yyyy-MM-dd HH:mm:ss"
        dfmatter.timeZone=TimeZone(abbreviation: "GMT")
        let date = dfmatter.date(from: self)
        let dateStamp:TimeInterval = (date?.timeIntervalSince1970)!
        let dateSt:Int = Int(dateStamp)
        return dateSt
    }
    ///时间转换 String->Date
    public func toDate() -> Date  {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
        formatter.timeZone=TimeZone(abbreviation: "Asia/Shanghai")
        return formatter.date(from: self)!
    }
    ///获取当前的天
    public func getToDay() ->String {
        let date:Date = self.toToDay()
        let todayS=date.toDateString()
        
        return todayS
    }
    ///当前的天
    public func toToDay() ->  Date {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
        formatter.timeZone=TimeZone(abbreviation: "Asia/Shanghai")
        return formatter.date(from: self)!
    }
    
    
    ///判断是否是当天
    public func isToDay() -> Bool {
        let currentDate = Date()
        let otherDate = self.toDate()
        let tempDate = Int(currentDate.timeIntervalSince(otherDate))
        return tempDate > 24*60*60
    }
    
    ///距现在多长时间
    public func distanceNow() -> Int {
        let currentDate = Date()
        let otherDate = self.toDate()
        let tempDate = Int(otherDate.timeIntervalSince(currentDate))
        return tempDate > 0 ? tempDate : 0
    }

    /// -------------------数字转换---------------------
    public func StringToFloat() ->Float {
         var cgFloat: CGFloat = 0
         if let doubleValue = Double(self)
         {
             cgFloat = CGFloat(doubleValue)
         }
         return Float(cgFloat)
     }
    
     //判断是否是整数
     public func isPurnInt() -> Bool {
         let scan: Scanner = Scanner(string: self)
         var val:Int = 0
         return scan.scanInt(&val) && scan.isAtEnd
     }
    
     //判断是否是float
//     public func isPurnFloat(string: String) -> Bool {
//         let scan: Scanner = Scanner(string: self)
//         var val:Float = 0
//         return scan.scanFloat(&val) && scan.isAtEnd
//     }
    
    
    /// ------------------空格处理---------------------
    /*
         *去掉首尾空格
         */
    public var removeHeadAndTailSpace:String {
        let whitespace = NSCharacterSet.whitespaces
        return self.trimmingCharacters(in: whitespace)
    }
    /*
     *去掉首尾空格 包括后面的换行 \n
     */
    public var removeHeadAndTailSpacePro:String {
        let whitespace = NSCharacterSet.whitespacesAndNewlines
        return self.trimmingCharacters(in: whitespace)
    }
    /*
     *去掉所有空格
     */
    public var removeAllSapce: String {
        return self.replacingOccurrences(of: " ", with: "", options: .literal, range: nil)
    }
    /*
     *去掉首尾空格 后 指定开头空格数
     */
    public func beginSpaceNum(num: Int) -> String {
        var beginSpace = ""
        for _ in 0..<num {
            beginSpace += " "
        }
        return beginSpace + self.removeHeadAndTailSpacePro
    }
    
    
    ///-------------------编解码---------------------
    // base64编码
     public func toBase64() -> String? {
         if let data = self.data(using: .utf8) {
             return data.base64EncodedString()
         }
         return nil
     }
     
     // base64解码
     public func fromBase64() -> String? {
         if let data = Data(base64Encoded: self) {
             return String(data: data, encoding: .utf8)
         }
         return nil
     }
     
     
     public func base64Encoding()->String {
         let plainData = self.data(using: String.Encoding.utf8)
         let base64String = plainData?.base64EncodedString(options: NSData.Base64EncodingOptions.init(rawValue: 0))
         return base64String!
     }
    
     public func base64Decoding()->String
     {
         var str = self.replacingOccurrences(of: " ", with: "")
         str = str.replacingOccurrences(of: "\n", with: "")
         if let tempData=NSData(base64Encoded: str, options: NSData.Base64DecodingOptions.init(rawValue: 0)){
             if let decodedString = NSString(data: tempData as Data, encoding: String.Encoding.utf8.rawValue){
                 return decodedString as String
             }
             return self
         }
         return self
     }
    
    

    ///转换汉字为拼音
    public func transformToPinYin() -> String {
        
        let mutableString = NSMutableString(string: self)
        CFStringTransform(mutableString, nil, kCFStringTransformToLatin, false)
        CFStringTransform(mutableString, nil, kCFStringTransformStripDiacritics, false)
        let string = String(mutableString)
        return string.replacingOccurrences(of: " ", with: "")
    }
}

extension String {
    ///-------------------字符串截取&位置处理---------------------
    ///Range->NSRange
    public func toNSRange(_ range: Range<String.Index>) -> NSRange {
        guard let from = range.lowerBound.samePosition(in: utf16), let to = range.upperBound.samePosition(in: utf16) else {
            return NSMakeRange(0, 0)
        }
        return NSMakeRange(utf16.distance(from: utf16.startIndex, to: from), utf16.distance(from: from, to: to))
    }
    ///NSRange->Range
    public func toRange(_ range: NSRange) -> Range<String.Index>? {
        guard let from16 = utf16.index(utf16.startIndex, offsetBy: range.location, limitedBy: utf16.endIndex) else { return nil }
        guard let to16 = utf16.index(from16, offsetBy: range.length, limitedBy: utf16.endIndex) else { return nil }
        guard let from = String.Index(from16, within: self) else { return nil }
        guard let to = String.Index(to16, within: self) else { return nil }
        return from ..< to
    }
    
    ///（如果backwards参数设置为true，则返回最后出现的位置）
    public func positionOf(sub:String, backwards:Bool = false)->Int {
        // 如果没有找到就返回-1
        var pos = -1
        if let range = range(of:sub, options: backwards ? .backwards : .literal ) {
            if !range.isEmpty {
                pos = self.distance(from:startIndex, to:range.lowerBound)
            }
        }
        return pos
    }
    /// 截取 subStr 之后的字符串 到结尾
    /// - Parameters:
    ///   - subStr: 固定的字符串之后
    ///   - backwards: 知否从字符串尾部开始搜索
    /// - Returns: 返回截取之后的字符串
    public func subStringAfter(subStr:String, backwards:Bool = false ) -> String{
        let startPos = self.positionOf(sub: subStr ,backwards: backwards)
        //没有找到就返回全部字符串
        if startPos == -1 {
            return self
        }
        return String(self[(startPos+subStr.count)...])
    }
    /// 从开头截取字符串到  subStr 之前的字符串
    /// - Parameters:
    ///   - subStr: 固定的字符串之后
    ///   - backwards: 知否从字符串尾部开始搜索
    /// - Returns: 返回截取之后的字符串
    public func subStringBefore(subStr:String, backwards:Bool = false ) -> String{
        let startPos = self.positionOf(sub: subStr ,backwards: backwards)
        //没有找到就返回全部字符串
        if startPos == -1 {
            return self
        }
        return String(self[..<(startPos)])
    }
    
    ///手机号隐藏中间四位
    public func hiddenPhoneCenter() -> String {
        if self.count != 11{
            return "****"
        }
        let start = self.index(self.startIndex, offsetBy: 3)
        let end = self.index(self.startIndex, offsetBy: 7)
        let range = Range(uncheckedBounds: (lower: start, upper: end))
        return self.replacingCharacters(in: range, with: "****")
    }
    
    /*
     字符串截取
     let str00 = "hello world"
     let str01 = str00[1..<str00.count-1]
     print(str00)
     print(str01)
     */
    public  subscript(value: NSRange) -> Substring {
        return self[value.lowerBound..<value.upperBound]
    }
    
    /*
     闭合截取
     let str00 = "hello world"
     let str01 = str00[1...str00.count]
     */
    public subscript(value: CountableClosedRange<Int>) -> Substring {
        get {
            guard let upperIndex = index(at: value.upperBound) else{
                guard let lowerIndex = index(at: value.lowerBound) else{
                    return self[self.startIndex...self.endIndex]
                }
                return self[lowerIndex...]
            }
            guard let lowerIndex = index(at: value.lowerBound) else{
                /// 这块表示 截取最后一个字母
                if upperIndex >= self.endIndex{
                    return self[self.startIndex...]
                }else{
                    return self[self.startIndex...upperIndex]
                }
            }
            /// 这块表示 截取最后一个字母
            if upperIndex >= self.endIndex{
                return self[lowerIndex...]
            }else{
                return self[lowerIndex...upperIndex]
            }
        }
    }
    /*
     非闭合截取
     let str00 = "hello world"
     let str01 = str00[1..<str00.count]
     */
    public  subscript(value: CountableRange<Int>) -> Substring {
        get {
            guard let upperIndex = index(at: value.upperBound) else{
                guard let lowerIndex = index(at: value.lowerBound) else{
                    return self[self.startIndex..<self.endIndex]
                }
                return self[lowerIndex..<self.endIndex]
            }
            guard let lowerIndex = index(at: value.lowerBound) else{
                return self[self.startIndex..<upperIndex]
            }
            return self[lowerIndex..<upperIndex]
        }
    }
    /*
     非闭合截取
     let str00 = "hello world"
     let str01 = str00[..<str00.count]
     */
    public  subscript(value: PartialRangeUpTo<Int>) -> Substring {
        get {
            guard let index = index(at: value.upperBound) else{
                return self[..<self.endIndex]
            }
            return self[..<index]
        }
    }
    /*
     闭合截取
     let str00 = "hello world"
     let str01 = str00[...str00.count]
     */
    public subscript(value: PartialRangeThrough<Int>) -> Substring {
        get {
            guard let index = index(at: value.upperBound) else{
                return self[..<self.endIndex]
            }
            return self[...index]
        }
    }
    /*
     闭合截取
     let str00 = "hello world"
     let str01 = str00[3...]
     */
    public  subscript(value: PartialRangeFrom<Int>) -> Substring {
        get {
            guard let index = index(at: value.lowerBound) else{
                return self[self.startIndex...]
            }
            /// 这块表示 截取最后一个字母
            if index >= self.endIndex{
                return self[self.startIndex...]
            }
            return self[index...]
        }
    }
    func index(at offset: Int) -> String.Index? {
        if self.count < offset {
            return nil
        }
        return index(startIndex, offsetBy: offset)
        
    }
}
